package com.github.authcloud.server.configure.filter.gateway;

import com.github.authcloud.server.configure.checker.UserWhiteBlackList;
import com.github.authcloud.server.configure.exception.IpRefuseException;
import com.github.authcloud.server.configure.properties.AuthCommonProperties;
import com.github.authcloud.server.configure.utils.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author : zhaoxuan
 * @version : 1.0
 * @date : 2021/8/22 14:47
 * @description : GatewayAuthRolePermissionFilter
 */
public class GatewayWhiteListFilter implements GlobalFilter, Ordered {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private UserWhiteBlackList userWhiteBlackList;
    @Resource
    private AuthCommonProperties authCommonProperties;

    @Override
    public int getOrder() {
        return -1;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String userIp = IpUtil.getIpAddress(exchange.getRequest());
        Route route =(Route) exchange.getAttributes().get(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        String serviceName = route.getId().replace("ReactiveCompositeDiscoveryClient_", "");

        List<String> needWhiteService = authCommonProperties.getNeedWhiteService();
        //未配置,则全部校验
        if (!needWhiteService.isEmpty()) {
            //配置了, 仅校验已配置的服务, 不在此列, 直接放行
            if (needWhiteService.stream().noneMatch(serviceName::equalsIgnoreCase)) {
                return chain.filter(exchange);
            }
        }
        if (!userWhiteBlackList.isInWhiteList(userIp)) {
            logger.warn("The IP[{}] address is not in the whitelist", userIp);
            throw new IpRefuseException("The IP address is not in the blacklist");
        }
        return chain.filter(exchange);
    }
}
